﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Sharp.DataTransferObject;
using Sharp.Infrastructure;
using Sharp.Infrastructure.Communication;
using Sharp.Platform;
using Sharp.Platform.Configuration;
using Sharp.Platform.Owin;
using Sharp.ServiceContracts;
using Sharp.WebBooter.Areas.Platform.Models;

namespace Sharp.WebBooter.Areas.Platform.Controllers
{
    //[Authorize]
    public class AccountController : Controller
    {

        public AccountController()
        {
        }


        //
        // GET: /Account/Login
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
            ViewBag.ReturnUrl = returnUrl;

            LoginViewModel model = new LoginViewModel
            {
                Name = CookieHelper.GetCookie("LoginedName")
            };

            return View(model);
        }


        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
#if DEBUG
            if (WebServer.GetIP() != "127.0.0.1")
#endif
            {
                if (System.Web.HttpContext.Current.Session["ValidateCode"] == null)
                {
                    ModelState.AddModelError("", "验证码失效，请重新登录");
                    return View(model);
                }
                if (System.Web.HttpContext.Current.Session["ValidateCode"].ToString() != model.ValidateCode)
                {
                    ModelState.AddModelError("", "验证码错误");
                    return View(model);
                }
            }

            var result = await SignInManager.PasswordSignInAsync(model.Name, model.Password, model.RememberMe, shouldLockout: false);

            ContactContext.Current.SystemCode = "Platform";

            switch (result)
            {
                case SignInStatus.Success:
                     
                    using (var proxy = new ServiceProxy<IUserService>())
                    {
                        var res = proxy.Channel.GetUserByName(model.Name);
                        ContactContext.Current.UserId = res.Data.Id;
                        ContactContext.Current.UserName = res.Data.UserName;

                        SharpUserManager.Current = new SharpUser(res.Data);
                    }

                    CookieHelper.SetCookie("LoginedName", model.Name, 36000);

                    return Redirect("~/");
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                case SignInStatus.Failure:
                default:
                    ModelState.AddModelError("", "无效的登录尝试。");
                    return View(model);
            }
        }

        public ActionResult LogOff()
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
            return RedirectToAction("Login");
        }

        #region 验证码

        [AllowAnonymous]
        public ActionResult GetValidateCode()
        {
            ValidateCode vCode = new ValidateCode();
            string code = vCode.CreateValidateCode(4);
            Session["ValidateCode"] = code;
            byte[] bytes = vCode.CreateValidateGraphic(code);
            return File(bytes, @"image/jpeg");
        }

        #endregion

        /// <summary>
        /// 忘记密码
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult ForgotPassword()
        {
            var model = new ForgotPasswordViewModel();
            return View("ForgotPassword", model);
        }

        /// <summary>
        /// 取回密码
        /// </summary>
        /// <param name="vm"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult ForgotPassword(ForgotPasswordViewModel vm)
        {
            using (var proxy = new ServiceProxy<IUserService>())
            {
                var config = SystemConfigManage.Read<PlatformInfo>();
                SmtpClient smtp = new SmtpClient
                {
                    Credentials = new NetworkCredential(config.EMailConfig.LoginName, config.EMailConfig.Password),
                    Port = 25,
                    Host = config.EMailConfig.SmtpServer,
                    EnableSsl = false
                };

                //proxy.SendEMail(vm.Email, config.EMailConfig.FromEMail, smtp);

                return View(vm);
            }
        }

        ///// <summary>
        ///// 重置密码
        ///// </summary>
        ///// <param name="token">防伪识别码</param>
        ///// <returns></returns>
        //[HttpGet]
        //public ActionResult ResetPassword(Guid token)
        //{
        //    var vm = new ResetPasswordViewModel
        //    {
        //        AntiForgeryToken = token.ToString()
        //    };
        //    return View(vm);
        //}

        ///// <summary>
        ///// 重置密码
        ///// </summary>
        ///// <param name="vm"></param>
        ///// <returns></returns>
        //[HttpPost]
        //public ActionResult ResetPassword(ResetPasswordViewModel vm)
        //{
        //    if (vm == null)
        //    {
        //        ModelState.AddModelError("", "提交数据出错。");
        //        return View(new ResetPasswordViewModel());
        //    }
        //    var proxy = ServiceLocator.Instance.GetService<IUserService>();

        //    var res = proxy.ResetPassword(vm.To<ResetPasswordDTO>());
        //    if (res.Err.Length > 0)
        //        ModelState.AddModelError("", res.Err);

        //    return View(vm);
        //}


        /// <summary>
        /// 保存订阅项配置
        /// </summary>
        /// <returns></returns>
        public ActionResult SaveSubscriber(Guid[] subscriberIds)
        {
            var res = new Result();
            try
            {
                var userId = SharpUserManager.Current.Id;
                var config = UserConfigManage.Read<UserConfig>(userId);
                config.Subscribers.Clear();
                for (var i = 0; i < subscriberIds.Length; i++)
                {
                    config.Subscribers.Add(new UserConfig.SubscriberItem()
                    {
                        Id = subscriberIds[i],
                        Order = i
                    });
                }

                UserConfigManage.Save(config);
            }
            catch (Exception ex)
            {
                res.InnerException = ex;
            }
            return this.JsonNet(res);
        }

        [HttpGet]
        public ActionResult ChangePassword()
        {
            var model = new ChangePassword();
            return View("ChangePassword", model);
        }

        [HttpPost]
        public ActionResult ChangePassword(ChangePassword vm)
        {
            if (vm == null)
            {
                return this.JsonNet(new Result() { Err = "提交数据出错。" });
            }
            if (vm.PasswordNew != vm.PasswordNewS)
            {
                return this.JsonNet(new Result() { Err = "两次输入新密码不一致，请重新输入！" });

            }
            using (var proxy = new ServiceProxy<IUserService>())
            {

                var res = proxy.Channel.ChangePassword(SharpUserManager.Current.UserName, vm.Password, vm.PasswordNew);

                return this.JsonNet(res);
            }
        }

        #region 帮助程序
        private SharpSignInManager _signInManager;
        private SharpUserManager _userManager;
        // 用于在添加外部登录名时提供 XSRF 保护
        private const string XsrfKey = "XsrfId";
        public SharpSignInManager SignInManager
        {
            get
            {
                return _signInManager ?? HttpContext.GetOwinContext().Get<SharpSignInManager>();
            }
            private set
            {
                _signInManager = value;
            }
        }

        public SharpUserManager UserManager
        {
            get
            {
                return _userManager ?? HttpContext.GetOwinContext().GetUserManager<SharpUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }
        private IAuthenticationManager AuthenticationManager
        {
            get
            {
                return HttpContext.GetOwinContext().Authentication;
            }
        }

        private void AddErrors(IdentityResult result)
        {
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError("", error);
            }
        }

        internal class ChallengeResult : HttpUnauthorizedResult
        {
            public ChallengeResult(string provider, string redirectUri)
                : this(provider, redirectUri, null)
            {
            }

            public ChallengeResult(string provider, string redirectUri, string userId)
            {
                LoginProvider = provider;
                RedirectUri = redirectUri;
                UserId = userId;
            }

            public string LoginProvider { get; set; }
            public string RedirectUri { get; set; }
            public string UserId { get; set; }

            public override void ExecuteResult(ControllerContext context)
            {
                var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
                if (UserId != null)
                {
                    properties.Dictionary[XsrfKey] = UserId;
                }
                context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
            }
        }
        #endregion
    }
}